//chatroom server
package main

import (
	"net"
	"fmt"
	"strings"
	"os"
	"log"
)

const (
	LOG_DIRECTORY = "./test.log"
)

var onlineConns = make(map[string]net.Conn)
var messageQueue =make(chan string, 1000)

var logFile *os.File
var logger *log.Logger

var quitChan =make(chan bool)

func CheckError(err error){
	if err != nil{
		//fmt.Println(err.Error(), po)
		//os.Exit(1)
		panic(err)
	}
}

//对信息进行处理
func ConsumeMessage(){
	for {
		select {
		case message := <- messageQueue:
			doProcessMessage(message)
		case <- quitChan:
			break

		}
	}
}

//信息处理的具体实现
func doProcessMessage(message string){

	contents := strings.Split(message, "#")
	if len(contents) > 1{
		addr := contents[0]
		//sendMessage := contents[1]
		sendMessage := strings.Join(contents[1:], "#")

		addr =strings.Trim(addr, " ")

		if conn, ok :=onlineConns[addr]; ok{
			_, err :=conn.Write([]byte(sendMessage))
			if err !=nil {
				fmt.Println("online conns send failure!")
			}
		}
	}else {
		contents := strings.Split(message, "*")
		if strings.ToUpper(contents[1]) == "LIST" {
			var ips string = ""
			for i := range onlineConns {
				ips = ips + "|" + i
			}
			if conn, ok := onlineConns[contents[0]]; ok {
				_, err := conn.Write([]byte(ips))
				if err != nil {
					fmt.Println("online conns send failure!")
				}
			}
		}
	}

}

//负责接收信息，并把信息放入接收队列
func ProcessInfo(conn net.Conn){
	buf := make([]byte, 1024)
	defer func(conn net.Conn) {
		addr := fmt.Sprintf("%s", conn.RemoteAddr())
		delete(onlineConns, addr)
		conn.Close()

		for i := range onlineConns{
			fmt.Println("online conns:"+i)
		}
	}(conn)

	for  {
		num, err :=conn.Read(buf)
		if err != nil{
			break
		}

		if num != 0{
/*			remoteAddr := conn.RemoteAddr()
			fmt.Println(remoteAddr,"received:", string(buf[0:num]))*/
			message := string(buf[0: num])
			messageQueue<- message
		}
	}
}

func main(){
	//打开日志文件
	logFile, err := os.OpenFile(LOG_DIRECTORY, os.O_RDWR|os.O_CREATE, 0)
	if err !=nil{
		fmt.Println("log file create failure!")
		os.Exit(-1)
	}
	defer logFile.Close()

	//利用go自带的log 将打开文件对象生成日志文件对象
	logger = log.New(logFile, "\r\n", log.Ldate|log.Ltime|log.Llongfile)

	listen_socket, err := net.Listen("tcp","127.0.0.1:8080")
	CheckError(err)

	defer listen_socket.Close()

	fmt.Println("Server is waiting...")

	logger.Println("I am writing the logs...")

	go ConsumeMessage()

	for {
		conn, err := listen_socket.Accept()
		CheckError(err)

		addr :=fmt.Sprintf("%s",conn.RemoteAddr())
		onlineConns[addr] = conn

		for i := range onlineConns{
			fmt.Println(i)
		}

		go ProcessInfo(conn)
	}

}
